home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 376-400 / 388 / dclock / dclock.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  41KB  |  1,808 lines

  1. /* DClock.c *****************************************************************
  2.  *
  3.  *    DClock --------    A Dumb Clock utility, my idea of how a clock
  4.  *            should really be like.
  5.  *
  6.  *    Author --------    Olaf 'Olsen' Barthel, MXM
  7.  *            Brabeckstrasse 35
  8.  *            D-3000 Hannover 71
  9.  *
  10.  *            Federal Republic of Germany
  11.  *
  12.  *    This  program  truly is in the PUBLIC DOMAIN.  Written on a cold
  13.  *    and  damp  September  evening,  hoping the next morning would be
  14.  *    better.
  15.  *
  16.  *    Compiled using Aztec C 5.0a, CygnusEd Professional 2 & ARexx.
  17.  *
  18.  ***************************************************************************/
  19.  
  20.     /* This belongs to ARP. */
  21.  
  22. #define NO_PRAGMAS
  23.  
  24. #include <libraries/arpbase.h>
  25.  
  26.     /* ARP help messages. */
  27.  
  28. char *CLI_Template    = "Quit/S,Info/S,Version/S,Quiet/S,Refresh/S,Readclock/S,Beep/K,Click/K,\
  29. Speech/K,Hour/K,Seconds/K,SetEnv/K,Countdown=Tea/K,Sound/K,Textcolour/K,Backcolour/K,\
  30. Clickvolume/K,Priority/K,Page/K,Alarm/K,Alarmtime/K";
  31.  
  32. char *CLI_Help        = "\nUsage: \33[1mDClock\33[0m [Quit] [Info] [Version] [Quiet] [Refresh] [Readclock]\
  33. \n              [Beep On|Off] [Click On|Off] [Speech On|Off]\
  34. \n              [Hour On|Off] [Seconds On|Off] [SetEnv On|Off]\
  35. \n              [Countdown/Tea #|Off] [Sound \"Name\"|Off]\
  36. \n              [Textcolour #] [Backcolour #]\
  37. \n              [Clickvolume 0..64] [Priority -128..127] [Page 0..4]\
  38. \n              [Alarm On|Off|Show] [Alarmtime HH:MM:SS]\n";
  39.  
  40.     /* Where to find the different arguments (quite a lot). */
  41.  
  42. #define ARG_QUIT     1
  43. #define ARG_INFO     2
  44. #define ARG_VERSION     3
  45. #define ARG_QUIET     4
  46. #define ARG_REFRESH     5
  47. #define ARG_READCLOCK     6
  48. #define ARG_BEEP     7
  49. #define ARG_CLICK     8
  50. #define ARG_SPEECH     9
  51. #define ARG_HOUR    10
  52. #define ARG_SECONDS    11
  53. #define ARG_SETENV    12
  54. #define ARG_COUNTDOWN    13
  55. #define ARG_SOUND    14
  56. #define ARG_TEXTCOLOUR    15
  57. #define ARG_BACKCOLOUR    16
  58. #define ARG_CLICKVOLUME    17
  59. #define ARG_PRIORITY    18
  60. #define ARG_PAGE    19
  61. #define ARG_ALARM    20
  62. #define ARG_ALARMTIME    21
  63.  
  64.     /* Pop-up requester support structure. */
  65.  
  66. struct PopSupport
  67. {
  68.     ULONG    ps_Flags;
  69.     LONG    ps_TimeOut;
  70. };
  71.  
  72.     /* Pop-up requester support flags. */
  73.  
  74. #define PS_CENTER    0x00000001    /* Center window on screen. */
  75. #define PS_TIMEOUT    0x00000002    /* Wait for timeout. */
  76. #define PS_DONTMOVE    0x00000004    /* Don't move the pointer. */
  77. #define PS_BEEP        0x00000008    /* Beep on startup. */
  78. #define PS_STAYACTIVE    0x00000010    /* Keep the window activated. */
  79.  
  80.     /* Prototypes. */
  81.  
  82. LONG    Chk_Abort(VOID);
  83. VOID    _wb_parse(VOID);
  84.  
  85. LONG    MovePointer(struct Screen *mp_Screen, LONG mp_X, LONG mp_Y);
  86. LONG    WriteConsole(struct Window *wc_Window, UBYTE *wc_String);
  87. VOID    CalcDimensions(UBYTE *cd_String, LONG *cd_Width, LONG *cd_Height, LONG cd_MaxWidth);
  88. VOID    EraseGadget(struct RastPort *RPort, struct Gadget *Gadget);
  89. LONG    PopRequest(struct Window *pr_ParentWindow, UBYTE *pr_TitleText, UBYTE *pr_BodyText, UBYTE *pr_PosText, UBYTE *pr_NegText, LONG pr_Default, struct PopSupport *pr_ExtraInfo);
  90. VOID    ProcessIcon(VOID);
  91. LONG    FindChunk(ULONG ChunkName,BPTR FileHandle);
  92. LONG    LoadChimeSound(char *Name);
  93.  
  94. VOID    main(int argc,char **argv);
  95.  
  96.     /* For Workbench startability we need access to the icon info. */
  97.  
  98. struct Library    *IconBase;
  99. BOOL         FromWorkbench = FALSE;
  100.  
  101.     /* Some more libraries... */
  102.  
  103. extern struct IntuitionBase    *IntuitionBase;
  104. extern struct GfxBase        *GfxBase;
  105. extern struct ExecBase        *SysBase;
  106.  
  107.     /* Main communication structure. */
  108.  
  109. struct DSeg *DSeg;
  110.  
  111.     /* Stubs, don't need these. */
  112.  
  113. LONG Chk_Abort(VOID) { return(0); }
  114. VOID _wb_parse(VOID) {}
  115.  
  116.     /* Our current version tag. */
  117.  
  118. const char *VersionTag = "$VER: DClock 1.27 (26 Jul 1990)\n\r";
  119.  
  120.     /* MovePointer(mp_Screen,mp_X,mp_Y) :
  121.      *
  122.      *    Moves the mouse pointer to a given position
  123.      *    on a screen.
  124.      */
  125.  
  126. LONG
  127. MovePointer(struct Screen *mp_Screen,LONG mp_X,LONG mp_Y)
  128. {
  129.     static struct InputEvent mp_StaticEvent =
  130.     {
  131.         NULL,
  132.         IECLASS_POINTERPOS,
  133.         0,
  134.         IECODE_NOBUTTON,
  135.         0,0,0,0
  136.     };
  137.  
  138.     struct MsgPort        *mp_InputPort;
  139.     struct IOStdReq        *mp_InputRequest;
  140.     struct InputEvent    *mp_FakeEvent;
  141.  
  142.     LONG mp_Success = FALSE;
  143.  
  144.     if(mp_InputPort = (struct MsgPort *)CreatePort(NULL,0))
  145.     {
  146.         if(mp_InputRequest = (struct IOStdReq *)CreateStdIO(mp_InputPort))
  147.         {
  148.             if(!OpenDevice("input.device",0,(struct IORequest *)mp_InputRequest,0))
  149.             {
  150.                 if(mp_FakeEvent = (struct InputEvent *)AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC))
  151.                 {
  152.                     CopyMem(&mp_StaticEvent,mp_FakeEvent,sizeof(struct InputEvent));
  153.  
  154.                     mp_InputRequest -> io_Command    = IND_WRITEEVENT;
  155.                     mp_InputRequest -> io_Flags    = 0;
  156.                     mp_InputRequest -> io_Length    = sizeof(struct InputEvent);
  157.                     mp_InputRequest -> io_Data    = (APTR)mp_FakeEvent;
  158.  
  159.                     mp_FakeEvent -> ie_X = mp_X;
  160.                     mp_FakeEvent -> ie_Y = mp_Y;
  161.  
  162.                     if(!(mp_Screen -> ViewPort . Modes & HIRES))
  163.                         mp_FakeEvent -> ie_X *= 2;
  164.  
  165.                     if(!(mp_Screen -> ViewPort . Modes & LACE))
  166.                         mp_FakeEvent -> ie_Y *= 2;
  167.  
  168.                     mp_FakeEvent -> ie_Y += (2 * mp_Screen -> TopEdge);
  169.  
  170.                     DoIO((struct IORequest *)mp_InputRequest);
  171.  
  172.                     mp_Success = TRUE;
  173.  
  174.                     FreeMem(mp_FakeEvent,sizeof(struct InputEvent));
  175.                 }
  176.  
  177.                 CloseDevice((struct IORequest *)mp_InputRequest);
  178.             }
  179.  
  180.             DeleteStdIO(mp_InputRequest);
  181.         }
  182.  
  183.         DeletePort(mp_InputPort);
  184.     }
  185.  
  186.     return(mp_Success);
  187. }
  188.  
  189.     /* WriteConsole(wc_Window,wc_String) :
  190.      *
  191.      *    Writes a string to a window (via console.device).
  192.      */
  193.  
  194. LONG
  195. WriteConsole(struct Window *wc_Window,UBYTE *wc_String)
  196. {
  197.     struct IOStdReq    *wc_ConWrite;
  198.     struct MsgPort    *wc_ConPort;
  199.  
  200.     LONG wc_Success = FALSE;
  201.  
  202.     if(wc_ConPort = (struct MsgPort *)CreatePort(NULL,0))
  203.     {
  204.         if(wc_ConWrite = (struct IOStdReq *)CreateStdIO(wc_ConPort))
  205.         {
  206.             wc_ConWrite -> io_Data    = (APTR)wc_Window;
  207.             wc_ConWrite -> io_Length= sizeof(struct Window);
  208.  
  209.             if(!OpenDevice("console.device",0,(struct IORequest *)wc_ConWrite,0))
  210.             {
  211.                 wc_ConWrite -> io_Command    = CMD_WRITE;
  212.                 wc_ConWrite -> io_Data        = (APTR)"\2330 p";
  213.                 wc_ConWrite -> io_Length    = -1;
  214.  
  215.                 DoIO((struct IORequest *)wc_ConWrite);
  216.  
  217.                 wc_ConWrite -> io_Data        = (APTR)wc_String;
  218.                 wc_ConWrite -> io_Length    = -1;
  219.  
  220.                 DoIO((struct IORequest *)wc_ConWrite);
  221.  
  222.                 wc_Success = TRUE;
  223.  
  224.                 CloseDevice((struct IORequest *)wc_ConWrite);
  225.             }
  226.  
  227.             DeleteStdIO(wc_ConWrite);
  228.         }
  229.  
  230.         DeletePort(wc_ConPort);
  231.     }
  232.  
  233.     return(wc_Success);
  234. }
  235.  
  236.     /* CalcDimensions(cd_String,cd_Width,cd_Height,cd_MaxWidth) :
  237.      *
  238.      *    Calculates the width and height of a formatted
  239.      *    string block.
  240.      */
  241.  
  242. VOID
  243. CalcDimensions(UBYTE *cd_String,LONG *cd_Width,LONG *cd_Height,LONG cd_MaxWidth)
  244. {
  245.     LONG i,cd_InLine = 0,cd_NumLines = 0;
  246.  
  247.     *cd_Width = *cd_Height = 0;
  248.  
  249.     for(i = 0 ; i < strlen(cd_String) ; i++)
  250.     {
  251.         if(cd_String[i] == '\n' || cd_InLine == cd_MaxWidth)
  252.         {
  253.             if(cd_InLine > *cd_Width)
  254.                 *cd_Width = cd_InLine;
  255.  
  256.             cd_NumLines++;
  257.             cd_InLine = 0;
  258.  
  259.             continue;
  260.         }
  261.  
  262.         if(cd_String[i] == '\33')
  263.         {
  264.             while(cd_String[i] != 'm' && cd_String[i] != 'w' && i < strlen(cd_String))
  265.                 i++;
  266.  
  267.             if(i >= strlen(cd_String))
  268.                 i = strlen(cd_String) - 1;
  269.  
  270.             continue;
  271.         }
  272.  
  273.         if(cd_String[i] < ' ')
  274.             continue;
  275.  
  276.         cd_InLine++;
  277.     }
  278.  
  279.     *cd_Height = cd_NumLines;
  280.  
  281.     if(cd_InLine > *cd_Width)
  282.         *cd_Width = cd_InLine;
  283. }
  284.  
  285.     /* EraseGadget(RPort,Gadget) :
  286.      *
  287.      *    Clears the background of a gadget.
  288.      */
  289.  
  290. VOID
  291. EraseGadget(struct RastPort *RPort,struct Gadget *Gadget)
  292. {
  293.     SetAPen(RPort,2);
  294.  
  295.     SetDrMd(RPort,JAM1);
  296.  
  297.     RectFill(RPort,Gadget -> LeftEdge,Gadget -> TopEdge,Gadget -> LeftEdge + Gadget -> Width - 1,Gadget -> TopEdge + Gadget -> Height - 1);
  298.  
  299.     SetAPen(RPort,1);
  300. }
  301.  
  302.     /* PopRequest(pr_ParentWindow,pr_TitleText,pr_BodyText,pr_PosText,pr_NegText,pr_Default,pr_ExtraInfo) :
  303.      *
  304.      *    Creates a pop-up requester, note: this function is reentrant,
  305.      *    just like all functions above.
  306.      */
  307.  
  308. LONG
  309. PopRequest(struct Window *pr_ParentWindow,UBYTE *pr_TitleText,UBYTE *pr_BodyText,UBYTE *pr_PosText,UBYTE *pr_NegText,LONG pr_Default,struct PopSupport *pr_ExtraInfo)
  310. {
  311.     static struct NewWindow pr_StaticNewWindow =
  312.     {
  313.         0,0,
  314.         0,1,
  315.         0,1,
  316.         VANILLAKEY | MOUSEBUTTONS | GADGETUP | CLOSEWINDOW,
  317.         RMBTRAP | WINDOWDRAG | WINDOWDEPTH,
  318.         (struct Gadget *)NULL,
  319.         (struct Image *)NULL,
  320.         (STRPTR)NULL,
  321.         (struct Screen *)NULL,
  322.         (struct BitMap *)NULL,
  323.         0,0,
  324.         0,0,
  325.         WBENCHSCREEN
  326.     };
  327.  
  328.     static struct Gadget pr_StaticGadget =
  329.     {
  330.         (struct Gadget *)NULL,
  331.         0,0,
  332.         0,0,
  333.         GADGHBOX,
  334.         RELVERIFY | GADGIMMEDIATE,
  335.         BOOLGADGET,
  336.         (APTR)NULL,
  337.         (APTR)NULL,
  338.         (struct IntuiText *)NULL,
  339.         NULL,
  340.         (APTR)NULL,
  341.         0,
  342.         (APTR)NULL
  343.     };
  344.  
  345.     static struct TextAttr pr_TextAttr =
  346.     {
  347.         (UBYTE *)"topaz.font",
  348.         8,
  349.         FS_NORMAL,
  350.         FPF_ROMFONT
  351.     };
  352.  
  353.     struct NewWindow    *pr_NewWindow;
  354.     struct Window        *pr_Window;
  355.     struct IntuiMessage    *pr_IMsg;
  356.     struct Gadget        *pr_PosGadget = NULL,*pr_NegGadget = NULL,*pr_TempGadget;
  357.  
  358.     struct Screen         pr_Screen,*pr_FirstScreen;
  359.     struct TextFont        *pr_TextFont;
  360.  
  361.     LONG             pr_Width,pr_Height;
  362.     LONG             pr_Result = FALSE;
  363.  
  364.     LONG             pr_TickCount = 0;
  365.  
  366.     ULONG             pr_IntuiLock;
  367.  
  368.     if(!pr_BodyText)
  369.         return(pr_Result);
  370.  
  371.     if(!(pr_NewWindow = (struct NewWindow *)AllocMem(sizeof(struct NewWindow),MEMF_PUBLIC)))
  372.         return(pr_Result);
  373.  
  374.     CopyMem(&pr_StaticNewWindow,pr_NewWindow,sizeof(struct NewWindow));
  375.  
  376.     pr_IntuiLock = LockIBase(NULL);
  377.  
  378.     pr_FirstScreen = IntuitionBase -> FirstScreen;
  379.  
  380.     UnlockIBase(pr_IntuiLock);
  381.  
  382.     if(pr_ParentWindow)
  383.     {
  384.         pr_NewWindow -> Type    = CUSTOMSCREEN;
  385.         pr_NewWindow -> Screen    = pr_ParentWindow -> WScreen;
  386.     }
  387.     else
  388.         OpenWorkBench();
  389.  
  390.     if(!GetScreenData(&pr_Screen,sizeof(struct Screen),pr_NewWindow -> Type,pr_NewWindow -> Screen))
  391.     {
  392.         FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  393.         return(pr_Result);
  394.     }
  395.  
  396.     CalcDimensions(pr_BodyText,&pr_Width,&pr_Height,(pr_Screen . Width - 6) / 8);
  397.  
  398.     if(pr_Height > (pr_Screen . Height - 15 - 13) / 8)
  399.     {
  400.         FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  401.         return(pr_Result);
  402.     }
  403.  
  404.     pr_NewWindow -> Width    = pr_Width * 8 + 6 + 4;
  405.     pr_NewWindow -> Height    = pr_Height * 8 + 15 + 19 + 2;
  406.  
  407.     if(pr_TitleText)
  408.         pr_NewWindow -> Title = pr_TitleText;
  409.     else
  410.         pr_NewWindow -> Title = (UBYTE *)"System Request";
  411.  
  412.     if(!pr_PosText && !pr_NegText)
  413.         pr_NegText = (UBYTE *)"Okay";
  414.  
  415.     if(pr_PosText)
  416.     {
  417.         if(!(pr_PosGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC)))
  418.         {
  419.             FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  420.             return(pr_Result);
  421.         }
  422.  
  423.         CopyMem(&pr_StaticGadget,pr_PosGadget,sizeof(struct Gadget));
  424.  
  425.         pr_PosGadget -> Width    = 8 * strlen(pr_PosText) + 4;
  426.         pr_PosGadget -> Height    = 8 + 2;
  427.  
  428.         pr_PosGadget -> LeftEdge= 3 + 2 + 3;
  429.         pr_PosGadget -> TopEdge    = pr_NewWindow -> Height - 13 - 1;
  430.     }
  431.  
  432.     if(pr_NegText)
  433.     {
  434.         if(!(pr_NegGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC)))
  435.         {
  436.             FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  437.  
  438.             if(pr_PosGadget)
  439.                 FreeMem(pr_PosGadget,sizeof(struct Gadget));
  440.  
  441.             return(pr_Result);
  442.         }
  443.  
  444.         CopyMem(&pr_StaticGadget,pr_NegGadget,sizeof(struct Gadget));
  445.  
  446.         pr_NegGadget -> Width    = 8 * strlen(pr_NegText) + 4;
  447.         pr_NegGadget -> Height    = 8 + 2;
  448.  
  449.         pr_Width = pr_NegGadget -> Width + 6 + 4 + 6;
  450.  
  451.         if(pr_PosGadget)
  452.             pr_Width += (pr_PosGadget -> Width + 12);
  453.  
  454.         if(pr_NewWindow -> Width < pr_Width)
  455.             pr_NewWindow -> Width = pr_Width;
  456.  
  457.         pr_NegGadget -> LeftEdge= pr_NewWindow -> Width - pr_NegGadget -> Width - 3 - 2 - 3;
  458.         pr_NegGadget -> TopEdge    = pr_NewWindow -> Height - 13 - 1;
  459.  
  460.         pr_NegGadget -> GadgetID= 1;
  461.     }
  462.  
  463.     if(!pr_NegGadget && pr_NewWindow -> Width < pr_PosGadget -> Width + 6 + 4 + 6)
  464.         pr_NewWindow -> Width = pr_PosGadget -> Width + 6 + 4 + 6;
  465.  
  466.     if(pr_Default && !pr_PosGadget)
  467.         pr_Default = FALSE;
  468.  
  469.     if(!pr_Default && !pr_NegGadget)
  470.         pr_Default = TRUE;
  471.  
  472.     if(pr_Default)
  473.         pr_TempGadget = pr_PosGadget;
  474.     else
  475.         pr_TempGadget = pr_NegGadget;
  476.  
  477.     pr_NewWindow -> LeftEdge= pr_Screen . MouseX - (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2);
  478.     pr_NewWindow -> TopEdge    = pr_Screen . MouseY - (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2);
  479.  
  480.     while(pr_NewWindow -> LeftEdge < 0)
  481.         pr_NewWindow -> LeftEdge++;
  482.  
  483.     while(pr_NewWindow -> TopEdge < 0)
  484.         pr_NewWindow -> TopEdge++;
  485.  
  486.     while(pr_NewWindow -> LeftEdge + pr_NewWindow -> Width >= pr_Screen . Width)
  487.         pr_NewWindow -> LeftEdge--;
  488.  
  489.     while(pr_NewWindow -> TopEdge + pr_NewWindow -> Height >= pr_Screen . Height)
  490.         pr_NewWindow -> TopEdge--;
  491.  
  492.     if(!(pr_TextFont = (struct TextFont *)OpenFont(&pr_TextAttr)))
  493.     {
  494.         if(pr_PosGadget)
  495.             FreeMem(pr_PosGadget,sizeof(struct Gadget));
  496.  
  497.         if(pr_NegGadget)
  498.             FreeMem(pr_NegGadget,sizeof(struct Gadget));
  499.  
  500.         FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  501.  
  502.         return(pr_Result);
  503.     }
  504.  
  505.     if(pr_ExtraInfo)
  506.     {
  507.         if(pr_ExtraInfo -> ps_Flags & PS_CENTER)
  508.         {
  509.             pr_NewWindow -> LeftEdge    = (pr_Screen . Width - pr_NewWindow -> Width) / 2;
  510.             pr_NewWindow -> TopEdge        = (pr_Screen . Height - pr_NewWindow -> Height) / 2;
  511.         }
  512.  
  513.         if(pr_ExtraInfo -> ps_Flags & PS_TIMEOUT)
  514.             pr_NewWindow -> IDCMPFlags |= INTUITICKS;
  515.  
  516.         if(pr_ExtraInfo -> ps_Flags & PS_STAYACTIVE)
  517.             pr_NewWindow -> IDCMPFlags |= INACTIVEWINDOW;
  518.     }
  519.  
  520.     if(!(pr_Window = (struct Window *)OpenWindow(pr_NewWindow)))
  521.     {
  522.         CloseFont(pr_TextFont);
  523.  
  524.         if(pr_PosGadget)
  525.             FreeMem(pr_PosGadget,sizeof(struct Gadget));
  526.  
  527.         if(pr_NegGadget)
  528.             FreeMem(pr_NegGadget,sizeof(struct Gadget));
  529.  
  530.         FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  531.  
  532.         return(pr_Result);
  533.     }
  534.  
  535.     SetFont(pr_Window -> RPort,pr_TextFont);
  536.  
  537.     WriteConsole(pr_Window,pr_BodyText);
  538.  
  539.     if(pr_PosGadget)
  540.     {
  541.         AddGadget(pr_Window,pr_PosGadget,1);
  542.  
  543.         EraseGadget(pr_Window -> RPort,pr_PosGadget);
  544.  
  545.         Move(pr_Window -> RPort,pr_PosGadget -> LeftEdge + 2,pr_PosGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline);
  546.         Text(pr_Window -> RPort,pr_PosText,strlen(pr_PosText));
  547.     }
  548.  
  549.     if(pr_NegGadget)
  550.     {
  551.         AddGadget(pr_Window,pr_NegGadget,1);
  552.  
  553.         EraseGadget(pr_Window -> RPort,pr_NegGadget);
  554.  
  555.         Move(pr_Window -> RPort,pr_NegGadget -> LeftEdge + 2,pr_NegGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline);
  556.         Text(pr_Window -> RPort,pr_NegText,strlen(pr_NegText));
  557.     }
  558.  
  559.     MoveScreen(pr_Window -> WScreen,0,- pr_Window -> WScreen -> TopEdge);
  560.     ScreenToFront(pr_Window -> WScreen);
  561.     ActivateWindow(pr_Window);
  562.  
  563.     if(pr_ExtraInfo && pr_ExtraInfo -> ps_Flags & PS_DONTMOVE)
  564.         goto Skip1;
  565.  
  566.     MovePointer(pr_Window -> WScreen,
  567.         pr_Window -> LeftEdge + (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2),
  568.         pr_Window -> TopEdge + (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2));
  569.  
  570. Skip1:    if(pr_ExtraInfo)
  571.     {
  572.         if(pr_ExtraInfo -> ps_Flags & PS_BEEP)
  573.             DisplayBeep(pr_Window -> WScreen);
  574.  
  575.         if(pr_ExtraInfo -> ps_Flags & PS_TIMEOUT)
  576.             pr_TickCount = pr_ExtraInfo -> ps_TimeOut * 10;
  577.     }
  578.  
  579.     FOREVER
  580.     {
  581.         ULONG pr_Class,pr_Code,pr_Qualifier;
  582.         struct Gadget *pr_Gadget;
  583.  
  584.         WaitPort(pr_Window -> UserPort);
  585.  
  586.         if(pr_IMsg = (struct IntuiMessage *)GetMsg(pr_Window -> UserPort))
  587.         {
  588.             pr_Class    = pr_IMsg -> Class;
  589.             pr_Code        = pr_IMsg -> Code;
  590.             pr_Qualifier    = pr_IMsg -> Qualifier;
  591.             pr_Gadget    = (struct Gadget *)pr_IMsg -> IAddress;
  592.  
  593.             ReplyMsg((struct Message *)pr_IMsg);
  594.  
  595.             if(pr_Class == INTUITICKS)
  596.             {
  597.                 if(pr_TickCount)
  598.                     pr_TickCount--;
  599.                 else
  600.                 {
  601.                     pr_Result = pr_Default;
  602.                     break;
  603.                 }
  604.  
  605.                 continue;
  606.             }
  607.  
  608.             if(pr_Class == INACTIVEWINDOW)
  609.             {
  610.                 MoveScreen(pr_Window -> WScreen,0,- pr_Window -> WScreen -> TopEdge);
  611.                 ScreenToFront(pr_Window -> WScreen);
  612.                 ActivateWindow(pr_Window);
  613.  
  614.                 if(!(pr_ExtraInfo -> ps_Flags & PS_DONTMOVE))
  615.                 {
  616.                     MovePointer(pr_Window -> WScreen,
  617.                         pr_Window -> LeftEdge + (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2),
  618.                         pr_Window -> TopEdge + (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2));
  619.                 }
  620.  
  621.                 if(pr_ExtraInfo -> ps_Flags & PS_BEEP)
  622.                     DisplayBeep(pr_Window -> WScreen);
  623.  
  624.                 continue;
  625.             }
  626.  
  627.             if(pr_Class == GADGETUP)
  628.             {
  629.                 if(pr_Gadget -> GadgetID == 0)
  630.                     pr_Result = TRUE;
  631.  
  632.                 break;
  633.             }
  634.  
  635.             if(pr_Class == CLOSEWINDOW)
  636.                 break;
  637.  
  638.             if(pr_Class == VANILLAKEY)
  639.             {
  640.                 pr_Code = Toupper(pr_Code);
  641.  
  642.                 if((pr_Code == 'Y' || pr_Code == 'J' || pr_Code == 'V' || pr_Code == 'C' || pr_Code == 'R' || pr_Code == '\r') && pr_PosText)
  643.                 {
  644.                     pr_Result = TRUE;
  645.                     break;
  646.                 }
  647.  
  648.                 if((pr_Code == 'N' || pr_Code == 'Q' || pr_Code == 'B' || pr_Code == '\33') && pr_NegText)
  649.                     break;
  650.  
  651.                 continue;
  652.             }
  653.  
  654.             if(pr_Class == MOUSEBUTTONS && pr_Code == MENUDOWN)
  655.             {
  656.                 MovePointer(pr_Window -> WScreen,
  657.                     pr_Window -> LeftEdge+ (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2),
  658.                     pr_Window -> TopEdge + (pr_TempGadget -> TopEdge  + pr_TempGadget -> Height / 2));
  659.             }
  660.         }
  661.     }
  662.  
  663.     CloseFont(pr_TextFont);
  664.  
  665.     if(pr_PosGadget)
  666.     {
  667.         RemoveGadget(pr_Window,pr_PosGadget);
  668.         FreeMem(pr_PosGadget,sizeof(struct Gadget));
  669.     }
  670.  
  671.     if(pr_NegGadget)
  672.     {
  673.         RemoveGadget(pr_Window,pr_NegGadget);
  674.         FreeMem(pr_NegGadget,sizeof(struct Gadget));
  675.     }
  676.  
  677.     FreeMem(pr_NewWindow,sizeof(struct NewWindow));
  678.  
  679.     if(pr_FirstScreen != pr_Window -> WScreen)
  680.         ScreenToBack(pr_Window -> WScreen);
  681.  
  682.     CloseWindow(pr_Window);
  683.  
  684.     return(pr_Result);
  685. }
  686.  
  687.     /* FindChunk(ChunkName,FileHandle):
  688.      *
  689.      *    Tries to locate a an iff-chunk inside a file.
  690.      */
  691.  
  692. LONG
  693. FindChunk(ULONG ChunkName,BPTR FileHandle)
  694. {
  695.     LONG     OldPosition;
  696.     ULONG    FormType = 0;
  697.  
  698.         /* The format of a typical IFF-chunk. */
  699.  
  700.     struct
  701.     {
  702.         ULONG    IFF_Type;
  703.         ULONG    IFF_Length;
  704.     } Chunk;
  705.  
  706.         /* Remember initial file position. */
  707.  
  708.     OldPosition = Seek(FileHandle,0,OFFSET_CURRENT);
  709.  
  710.         /* Try to find it. */
  711.  
  712.     FOREVER
  713.     {
  714.             /* Read the first bytes. */
  715.  
  716.         if(Read(FileHandle,&Chunk,sizeof(Chunk)) != sizeof(Chunk))
  717.         {
  718.             Seek(FileHandle,OldPosition,OFFSET_BEGINNING);
  719.             return(FALSE);
  720.         }
  721.  
  722.             /* Is it a FORM-chunk? */
  723.  
  724.         if(OldPosition == 0 && FormType == 0 && Chunk . IFF_Type == 'FORM')
  725.         {
  726.             Read(FileHandle,&FormType,sizeof(LONG));
  727.  
  728.                 /* Check the form type. */
  729.  
  730.             if(FormType == ChunkName)
  731.                 return(TRUE);
  732.  
  733.             continue;
  734.         }
  735.  
  736.             /* Is it the chunk type we want? */
  737.  
  738.         if(Chunk . IFF_Type == ChunkName)
  739.             return(TRUE);
  740.  
  741.             /* Skip chunk. */
  742.  
  743.         Seek(FileHandle,Chunk . IFF_Length,OFFSET_CURRENT);
  744.     }
  745. }
  746.  
  747.     /* LoadChimeSound(Name):
  748.      *
  749.      *    Loads an IFF-8SVX-soundfile to be used as the hour
  750.      *    chime sound.
  751.      */
  752.  
  753. LONG
  754. LoadChimeSound(char *Name)
  755. {
  756.     BPTR SoundHandle;
  757.  
  758.     APTR SoundData;
  759.     LONG SoundRate,SoundLength,SoundVolume;
  760.  
  761.         /* The format of the VoiceHeader chunk. */
  762.  
  763.     struct
  764.     {
  765.         ULONG    oneShotHiSamples,
  766.             repeatHiSamples,
  767.             samplesPerHiCycle;
  768.         UWORD    samplesPerSec;
  769.         UBYTE    ctOctave,
  770.             sCompression;
  771.         LONG    volume;
  772.     } VoiceHeader;
  773.  
  774.         /* No name? Reset to defaults. */
  775.  
  776.     if(!Strcmp(Name,"OFF"))
  777.     {
  778.         ObtainSemaphore(DSeg -> SoundSemaphore);
  779.  
  780.             /* Free the memory. */
  781.  
  782.         if(DSeg -> SoundLength && DSeg -> SoundData)
  783.             FreeMem(DSeg -> SoundData,DSeg -> SoundLength);
  784.  
  785.             /* Mark sound slot as vacant. */
  786.  
  787.         DSeg -> SoundLength    = 0;
  788.         DSeg -> SoundData    = NULL;
  789.  
  790.         ReleaseSemaphore(DSeg -> SoundSemaphore);
  791.  
  792.         return(TRUE);
  793.     }
  794.  
  795.         /* Open the file for reading. */
  796.  
  797.     if(!(SoundHandle = Open(Name,MODE_OLDFILE)))
  798.     {
  799.         if(FromWorkbench)
  800.             PopRequest(NULL,"DClock problem:","No such sound file found!",NULL,"Continue?",FALSE,NULL);
  801.         else
  802.             Puts("\33[1mDClock:\33[0m No such sound file found!");
  803.  
  804.         return(FALSE);
  805.     }
  806.  
  807.         /* Is it a sound file? */
  808.  
  809.     if(!FindChunk('8SVX',SoundHandle))
  810.     {
  811.         Close(SoundHandle);
  812.  
  813.         if(FromWorkbench)
  814.             PopRequest(NULL,"DClock problem:","File is not an IFF-8SVX-file!",NULL,"Continue?",FALSE,NULL);
  815.         else
  816.             Puts("\33[1mDClock:\33[0m File is not an IFF-8SVX-file!");
  817.  
  818.         return(FALSE);
  819.     }
  820.  
  821.         /* Look for the VoiceHeader. */
  822.  
  823.     if(!FindChunk('VHDR',SoundHandle))
  824.     {
  825.         if(FromWorkbench)
  826.             PopRequest(NULL,"DClock problem:","Didn't find VHDR chunk!",NULL,"Continue?",FALSE,NULL);
  827.         else
  828.             Puts("\33[1mDClock:\33[0m Didn't find VHDR chunk!");
  829.  
  830.         Close(SoundHandle);
  831.         return(FALSE);
  832.     }
  833.  
  834.         /* Read the header. */
  835.  
  836.     if(Read(SoundHandle,&VoiceHeader,sizeof(VoiceHeader)) != sizeof(VoiceHeader))
  837.     {
  838.         if(FromWorkbench)
  839.             PopRequest(NULL,"DClock problem:","Error while reading file!",NULL,"Continue?",FALSE,NULL);
  840.         else
  841.             Puts("\33[1mDClock:\33[0m Error while reading file!");
  842.  
  843.         Close(SoundHandle);
  844.         return(FALSE);
  845.     }
  846.  
  847.         /* Fill in the more important information. */
  848.  
  849.     SoundLength    = VoiceHeader . oneShotHiSamples + VoiceHeader . repeatHiSamples;
  850.     SoundRate    = ((GfxBase -> DisplayFlags & PAL) ? 3546895 : 3579545) / VoiceHeader . samplesPerSec;
  851.     SoundVolume    = (VoiceHeader . volume > 64 ? 64 : VoiceHeader . volume);
  852.  
  853.         /* Proceed with the body chunk. */
  854.  
  855.     if(!FindChunk('BODY',SoundHandle))
  856.     {
  857.         if(FromWorkbench)
  858.             PopRequest(NULL,"DClock problem:","Didn't find BODY chunk!",NULL,"Continue?",FALSE,NULL);
  859.         else
  860.             Puts("\33[1mDClock:\33[0m Didn't find BODY chunk!");
  861.  
  862.         Close(SoundHandle);
  863.         return(FALSE);
  864.     }
  865.  
  866.         /* Allocate space for the sound data. */
  867.  
  868.     if(!(SoundData = (APTR)AllocMem(SoundLength,MEMF_PUBLIC | MEMF_CHIP)))
  869.     {
  870.         if(FromWorkbench)
  871.             PopRequest(NULL,"DClock problem:","Not enough memory for sound data!",NULL,"Continue?",FALSE,NULL);
  872.         else
  873.             Puts("\33[1mDClock:\33[0m Not enough memory for sound data!");
  874.  
  875.         Close(SoundHandle);
  876.         return(FALSE);
  877.     }
  878.  
  879.         /* Read the sound data. */
  880.  
  881.     if(Read(SoundHandle,SoundData,SoundLength) != SoundLength)
  882.     {
  883.         if(FromWorkbench)
  884.             PopRequest(NULL,"DClock problem:","Error while reading file!",NULL,"Continue?",FALSE,NULL);
  885.         else
  886.             Puts("\33[1mDClock:\33[0m Error while reading file!");
  887.  
  888.         FreeMem(SoundData,SoundLength);
  889.         Close(SoundHandle);
  890.         return(FALSE);
  891.     }
  892.  
  893.         /* Close the file. */
  894.  
  895.     Close(SoundHandle);
  896.  
  897.         /* Lock access to sound data. */
  898.  
  899.     ObtainSemaphore(DSeg -> SoundSemaphore);
  900.  
  901.         /* Free last sound. */
  902.  
  903.     if(DSeg -> SoundLength && DSeg -> SoundData)
  904.         FreeMem(DSeg -> SoundData,DSeg -> SoundLength);
  905.  
  906.         /* Fill in the data. */
  907.  
  908.     DSeg -> SoundData    = SoundData;
  909.     DSeg -> SoundLength    = SoundLength;
  910.     DSeg -> SoundRate    = SoundRate;
  911.     DSeg -> SoundVolume    = SoundVolume;
  912.  
  913.         /* Unlock it again. */
  914.  
  915.     ReleaseSemaphore(DSeg -> SoundSemaphore);
  916.  
  917.     return(TRUE);
  918. }
  919.  
  920.     /* ProcessIcon():
  921.      *
  922.      *    To add startability from Workbench this function
  923.      *    checks for the approritate tooltype entries.
  924.      */
  925.  
  926. VOID
  927. ProcessIcon()
  928. {
  929.     struct DiskObject *DiskObject;
  930.     extern struct WBStartup *WBenchMsg;
  931.     char *Option;
  932.  
  933.         /* No need to continue? */
  934.  
  935.     if(!DSeg || !FromWorkbench)
  936.     {
  937.         if(!DSeg && FromWorkbench)
  938.             PopRequest(NULL,"DClock problem:","Can't find \33[1m\"DClock-Handler\"\33[0m!\nCheck L: and current directory.",NULL,"Continue?",FALSE,NULL);
  939.  
  940.         return;
  941.     }
  942.  
  943.         /* Try to open the icon.library. */
  944.  
  945.     if(!(IconBase = (struct Library *)OpenLibrary("icon.library",0)))
  946.     {
  947.         PopRequest(NULL,"DClock problem:","Unable to open \33[1micon.library\33[0m!",NULL,"Continue?",FALSE,NULL);
  948.         return;
  949.     }
  950.  
  951.         /* Can we read the icon file please? */
  952.  
  953.     if(!(DiskObject = (struct DiskObject *)GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name)))
  954.     {
  955.         PopRequest(NULL,"DClock problem:","Couldn't read icon information file!",NULL,"Continue?",FALSE,NULL);
  956.  
  957.         CloseLibrary(IconBase);
  958.         return;
  959.     }
  960.  
  961.         /* Adjust Click volume? */
  962.  
  963.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"CLICKVOLUME"))
  964.     {
  965.         if(Atol(Option) > 64 || Atol(Option) < 0)
  966.             PopRequest(NULL,"DClock problem:","Illegal value for click volume (must be between 0 and 64)!",NULL,"Continue?",FALSE,NULL);
  967.         else
  968.             DSeg -> ClickVolume = Atol(Option);
  969.     }
  970.  
  971.         /* Adjust task priority? */
  972.  
  973.     if((Option = FindToolType(DiskObject -> do_ToolTypes,"PRIORITY")) && DSeg -> Child)
  974.     {
  975.         if(Atol(Option) > 127 || Atol(Option) < -128)
  976.             PopRequest(NULL,"DClock problem:","Illegal value for handler task priority (must be between -128 and 127)!",NULL,"Continue?",FALSE,NULL);
  977.         else
  978.         {
  979.             DSeg -> Priority = Atol(Option);
  980.             SetTaskPri(DSeg -> Child,DSeg -> Priority);
  981.         }
  982.     }
  983.  
  984.         /* Turn DisplayBeep() off? */
  985.  
  986.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"BEEP"))
  987.     {
  988.         if(!Strcmp(Option,"OFF"))
  989.             DSeg -> Beep = FALSE;
  990.         else
  991.         {
  992.             if(!Strcmp(Option,"ON"))
  993.                 DSeg -> Beep = TRUE;
  994.             else
  995.                 PopRequest(NULL,"DClock problem:","Beep settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  996.         }
  997.     }
  998.  
  999.         /* Turn keyboard click off? */
  1000.  
  1001.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"CLICK"))
  1002.     {
  1003.         if(!Strcmp(Option,"OFF"))
  1004.             DSeg -> Click = FALSE;
  1005.         else
  1006.         {
  1007.             if(!Strcmp(Option,"ON"))
  1008.                 DSeg -> Click = TRUE;
  1009.             else
  1010.                 PopRequest(NULL,"DClock problem:","Click settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1011.         }
  1012.     }
  1013.  
  1014.         /* Set text colour? */
  1015.  
  1016.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"TEXTCOLOUR"))
  1017.         DSeg -> TextColour = Atol(Option);
  1018.  
  1019.         /* Set background colour? */
  1020.  
  1021.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"BACKCOLOUR"))
  1022.         DSeg -> BackColour = Atol(Option);
  1023.  
  1024.         /* Turn alarm on? */
  1025.  
  1026.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"ALARM"))
  1027.     {
  1028.         if(!Strcmp(Option,"OFF"))
  1029.             DSeg -> Alarm = FALSE;
  1030.         else
  1031.         {
  1032.             if(!Strcmp(Option,"ON"))
  1033.                 DSeg -> Alarm = TRUE;
  1034.             else
  1035.                 PopRequest(NULL,"DClock problem:","Alarm settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1036.         }
  1037.     }
  1038.  
  1039.         /* Set alarm time? */
  1040.  
  1041.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"ALARMTIME"))
  1042.     {
  1043.         char TimeBuff[3];
  1044.         LONG TheTime;
  1045.  
  1046.         TimeBuff[2] = 0;
  1047.  
  1048.         TimeBuff[0] = Option[0];
  1049.         TimeBuff[1] = Option[1];
  1050.  
  1051.         TheTime = Atol(TimeBuff);
  1052.  
  1053.         if(TheTime >= 0 && TheTime <= 23)
  1054.             DSeg -> AlarmHour = TheTime;
  1055.         else
  1056.             PopRequest(NULL,"DClock problem:","Illegal value for alarm hour (must be between 0 and 23)!",NULL,"Continue?",FALSE,NULL);
  1057.  
  1058.         TimeBuff[0] = Option[3];
  1059.         TimeBuff[1] = Option[4];
  1060.  
  1061.         TheTime = Atol(TimeBuff);
  1062.  
  1063.         if(TheTime >= 0 && TheTime <= 59)
  1064.             DSeg -> AlarmMinute = TheTime;
  1065.         else
  1066.             PopRequest(NULL,"DClock problem:","Illegal value for alarm minute (must be between 0 and 59)!",NULL,"Continue?",FALSE,NULL);
  1067.  
  1068.         TimeBuff[0] = Option[6];
  1069.         TimeBuff[1] = Option[7];
  1070.  
  1071.         TheTime = Atol(TimeBuff);
  1072.  
  1073.         if(TheTime >= 0 && TheTime <= 59)
  1074.             DSeg -> AlarmSecond = TheTime;
  1075.         else
  1076.             PopRequest(NULL,"DClock problem:","Illegal value for alarm seconds (must be between 0 and 59)!",NULL,"Continue?",FALSE,NULL);
  1077.     }
  1078.  
  1079.         /* Set environment variables? */
  1080.  
  1081.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"SETENV"))
  1082.     {
  1083.         if(!Strcmp(Option,"OFF"))
  1084.             DSeg -> SetEnv = FALSE;
  1085.         else
  1086.         {
  1087.             if(!Strcmp(Option,"ON"))
  1088.                 DSeg -> SetEnv = TRUE;
  1089.             else
  1090.                 PopRequest(NULL,"DClock problem:","Environment settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1091.         }
  1092.     }
  1093.  
  1094.         /* Start countdown? */
  1095.  
  1096.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"COUNTDOWN"))
  1097.     {
  1098.         if(Atol(Option) > 0)
  1099.             DSeg -> Countdown = Atol(Option);
  1100.         else
  1101.             PopRequest(NULL,"DClock problem:","Countdown must be greater than 0!",NULL,"Continue?",FALSE,NULL);
  1102.     }
  1103.  
  1104.         /* Set hour chime? */
  1105.  
  1106.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"HOUR"))
  1107.     {
  1108.         if(!Strcmp(Option,"OFF"))
  1109.             DSeg -> Hour = FALSE;
  1110.         else
  1111.         {
  1112.             if(!Strcmp(Option,"ON"))
  1113.                 DSeg -> Hour = TRUE;
  1114.             else
  1115.                 PopRequest(NULL,"DClock problem:","Hour settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1116.         }
  1117.     }
  1118.  
  1119.         /* Turn seconds off? */
  1120.  
  1121.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"SECONDS"))
  1122.     {
  1123.         if(!Strcmp(Option,"OFF"))
  1124.             DSeg -> Seconds = FALSE;
  1125.         else
  1126.         {
  1127.             if(!Strcmp(Option,"ON"))
  1128.                 DSeg -> Seconds = TRUE;
  1129.             else
  1130.                 PopRequest(NULL,"DClock problem:","Second settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1131.         }
  1132.     }
  1133.  
  1134.         /* Load a chime sound? */
  1135.  
  1136.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"SOUND"))
  1137.         LoadChimeSound(Option);
  1138.  
  1139.         /* Show which page on startup? */
  1140.  
  1141.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"PAGE"))
  1142.     {
  1143.         if(Atol(Option) < 0 || Atol(Option) > 4 || (Atol(Option) == 4 && DSeg -> Countdown < 1))
  1144.             PopRequest(NULL,"DClock problem:","Illegal value for page!",NULL,"Continue?",FALSE,NULL);
  1145.         else
  1146.             DSeg -> Page = Atol(Option);
  1147.     }
  1148.  
  1149.         /* Turn the speech off? */
  1150.  
  1151.     if(Option = FindToolType(DiskObject -> do_ToolTypes,"SPEECH"))
  1152.     {
  1153.         if(!Strcmp(Option,"OFF"))
  1154.             DSeg -> Speech = FALSE;
  1155.         else
  1156.         {
  1157.             if(!Strcmp(Option,"ON"))
  1158.                 DSeg -> Speech = TRUE;
  1159.             else
  1160.                 PopRequest(NULL,"DClock problem:","Speech settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL);
  1161.         }
  1162.     }
  1163.  
  1164.         /* Read the system clock? */
  1165.  
  1166.     if(FindToolType(DiskObject -> do_ToolTypes,"READCLOCK"))
  1167.     {
  1168.         if(!ReadClock())
  1169.             PopRequest(NULL,"DClock problem:","Could not find battery backed up clock!",NULL,"Continue?",FALSE,NULL);
  1170.     }
  1171.  
  1172.         /* Free the rest... */
  1173.  
  1174.     FreeDiskObject(DiskObject);
  1175.  
  1176.     CloseLibrary(IconBase);
  1177. }
  1178.  
  1179.     /* main(argc,argv):
  1180.      *
  1181.      *    That's where all the trouble starts.
  1182.      */
  1183.  
  1184. VOID
  1185. main(int argc,char **argv)
  1186. {
  1187.     BOOL         Quiet = FALSE;
  1188.     struct Process    *ThatsMe = (struct Process *)SysBase -> ThisTask;
  1189.  
  1190.         /* Init important pointers. */
  1191.  
  1192.     if(!ThatsMe -> pr_CLI)
  1193.         FromWorkbench = TRUE;
  1194.  
  1195.         /* Are we already running? */
  1196.  
  1197.     DSeg = (struct DSeg *)FindPort(PORTNAME);
  1198.  
  1199.         /* Restart? */
  1200.  
  1201.     if(FromWorkbench && DSeg)
  1202.     {
  1203.         ProcessIcon();
  1204.         exit(RETURN_OK);
  1205.     }
  1206.  
  1207.         /* Yeah... push it! */
  1208.  
  1209.     if(FromWorkbench)
  1210.         goto PushIt;
  1211.  
  1212.         /* Be quiet? */
  1213.  
  1214.     if(argv[ARG_QUIET])
  1215.         Quiet = TRUE;
  1216.  
  1217.         /* No argument and DClock's already running? */
  1218.  
  1219.     if(argc < 2 && DSeg)
  1220.     {
  1221.         Printf("Can't install \33[1mDClock\33[0m, handler process \33[33malready running\33[31m\7!\n");
  1222.  
  1223.         exit(RETURN_OK);
  1224.     }
  1225.  
  1226.         /* Read the system clock? */
  1227.  
  1228.     if(argv[ARG_READCLOCK])
  1229.     {
  1230.         if(!ReadClock() && !Quiet)
  1231.             Puts("\33[1mDClock:\33[0m Could not find battery backed up clock.");
  1232.     }
  1233.  
  1234.         /* User wants information. */
  1235.  
  1236.     if(argv[ARG_INFO])
  1237.     {
  1238.         Printf("\n\33[1m\33[33mDClock\33[0m\33[31m - A \33[33mD\33[31mumb \33[33mClock\33[31m. Renders time and date\n");
  1239.         Printf("         into the Workbench title bar. Place\n");
  1240.         Printf("         \33[33mDClock-Handler\33[31m in L:, \33[33mDClock\33[31m somewhere\n");
  1241.         Printf("         in C: or in SYS:. Type '\33[1m\33[33mDClock\33[31m\33[0m' to\n");
  1242.         Printf("         install, '\33[1m\33[33mDClock quit\33[31m\33[0m' to remove.\n\n");
  1243.         Printf("         \33[33mDClock\33[31m is \33[1mfree\33[0m and in the \33[33m\33[1mPUBLIC-DOMAIN\33[31m\33[0m!\n\n");
  1244.  
  1245.         Printf("\33[1m\33[33mAuthor\33[31m\33[0m - Olaf Barthel, MXM\n");
  1246.         Printf("         Brabeckstrasse 35\n");
  1247.         Printf("         D-3000 Hannover 71\n\n");
  1248.  
  1249.         Printf("     Federal Republic of Germany.\n\n");
  1250.  
  1251.         exit(RETURN_OK);
  1252.     }
  1253.  
  1254.         /* Print current release version number. */
  1255.  
  1256.     if(argv[ARG_VERSION])
  1257.     {
  1258.         Printf("\33[1mDClock\33[0m version 1.%ld, created \33[33mThursday, 27-Jul-90, 11:32\33[31m.\n",DSeg ? DSeg -> Revision : REVISION);
  1259.         exit(RETURN_OK);
  1260.     }
  1261.  
  1262.         /* Terminate dumb clock? */
  1263.  
  1264.     if(argv[ARG_QUIT])
  1265.     {
  1266.         Printf("Removing \33[1m\33[33mDClock\33[31m\33[0m (DClock-Handler revision 1.%ld), ",DSeg ? DSeg -> Revision : -1);
  1267.  
  1268.             /* Segment not loaded. */
  1269.  
  1270.         if(!DSeg)
  1271.         {
  1272.             Printf("failed!\7\n");
  1273.             exit(RETURN_FAIL);
  1274.         }
  1275.  
  1276.             /* We are the caller. */
  1277.  
  1278.         DSeg -> Father = (struct Task *)ThatsMe;
  1279.  
  1280.             /* Child still present? */
  1281.  
  1282.         if(DSeg -> Child)
  1283.         {
  1284.             Signal(DSeg -> Child,SIGBREAKF_CTRL_D);
  1285.             Wait(SIGBREAKF_CTRL_D);
  1286.         }
  1287.  
  1288.             /* Remove port and associated data. */
  1289.  
  1290.         RemPort(&DSeg -> Port);
  1291.         FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
  1292.  
  1293.         if(DSeg -> SoundData && DSeg -> SoundLength)
  1294.             FreeMem(DSeg -> SoundData,DSeg -> SoundLength);
  1295.  
  1296.         FreeMem(DSeg -> SoundSemaphore,sizeof(struct SignalSemaphore));
  1297.  
  1298.         if(DSeg -> Segment)
  1299.             UnLoadSeg(DSeg -> Segment);
  1300.  
  1301.         FreeMem(DSeg,DSeg -> SegSize);
  1302.  
  1303.         Printf("OK.\n");
  1304.  
  1305.         exit(RETURN_OK);
  1306.     }
  1307.  
  1308.         /* Create global communication structure. */
  1309.  
  1310. PushIt:    if(!DSeg)
  1311.     {
  1312.         if(DSeg = (struct DSeg *)AllocMem(sizeof(struct DSeg),MEMF_PUBLIC | MEMF_CLEAR))
  1313.         {
  1314.             ULONG Micros;
  1315.  
  1316.                 /* Dummy MessagePort. */
  1317.  
  1318.             DSeg -> Port . mp_Flags            = PA_IGNORE;
  1319.             DSeg -> Port . mp_Node . ln_Pri        = 1;
  1320.             DSeg -> Port . mp_Node . ln_Type    = NT_MSGPORT;
  1321.             DSeg -> Port . mp_Node . ln_Name    = AllocMem(sizeof(PORTNAME),MEMF_PUBLIC);
  1322.             DSeg -> Child                = NULL;
  1323.             DSeg -> Father                = (struct Task *)ThatsMe;
  1324.             DSeg -> SoundSemaphore            = (struct SignalSemaphore *)AllocMem(sizeof(struct SignalSemaphore),MEMF_PUBLIC | MEMF_CLEAR);
  1325.  
  1326.             if(!DSeg -> Port . mp_Node . ln_Name || !DSeg -> SoundSemaphore)
  1327.                 goto Purge;
  1328.  
  1329.                 /* For future expansion of this structure;
  1330.                  * this will insure that any version of
  1331.                  * DClock will be able to free the memory
  1332.                  * occupied by the segment.
  1333.                  */
  1334.  
  1335.             DSeg -> SegSize            = sizeof(struct DSeg);
  1336.  
  1337.                 /* We'll wait for this signal to come from
  1338.                  * the handler process.
  1339.                  */
  1340.  
  1341.             DSeg -> RingBack        = SIGBREAKF_CTRL_C;
  1342.  
  1343.                 /* Enable beep and disable click feature. */
  1344.  
  1345.             DSeg -> Beep            = TRUE;
  1346.             DSeg -> Click            = FALSE;
  1347.  
  1348.                 /* So we have valid time counter. */
  1349.  
  1350.             CurrentTime(&DSeg -> LastSecs,&Micros);
  1351.  
  1352.                 /* Click volume and handler priority. */
  1353.  
  1354.             DSeg -> ClickVolume        = 64;
  1355.             DSeg -> Priority        = 5;
  1356.  
  1357.                 /* Rendering colours. */
  1358.  
  1359.             DSeg -> TextColour        = 0;
  1360.             DSeg -> BackColour        = 1;
  1361.  
  1362.                 /* Set alarm default. */
  1363.  
  1364.             DSeg -> Alarm            = FALSE;
  1365.  
  1366.             DSeg -> AlarmHour        = 12;
  1367.             DSeg -> AlarmMinute        = 0;
  1368.             DSeg -> AlarmSecond        = 0;
  1369.  
  1370.                 /* Disable countdown & hour chime. */
  1371.  
  1372.             DSeg -> Countdown        = 0;
  1373.             DSeg -> Hour            = FALSE;
  1374.  
  1375.                 /* Seconds are by default enabled. */
  1376.  
  1377.             DSeg -> Seconds            = TRUE;
  1378.  
  1379.                 /* Set environment variables. */
  1380.  
  1381.             DSeg -> SetEnv            = FALSE;
  1382.  
  1383.                 /* Install the current revision number. */
  1384.  
  1385.             DSeg -> Revision        = REVISION;
  1386.  
  1387.                 /* Init port. */
  1388.  
  1389.             strcpy(DSeg -> Port . mp_Node . ln_Name,PORTNAME);
  1390.  
  1391.             if(!FromWorkbench)
  1392.                 Printf("Installing \33[33m\33[1mDClock\33[0m\33[31m, ");
  1393.  
  1394.                 /* Load the handler code. */
  1395.  
  1396.             DSeg -> Segment = LoadSeg("DClock-Handler");
  1397.  
  1398.             if(!DSeg -> Segment)
  1399.                 DSeg -> Segment = LoadSeg("L:DClock-Handler");
  1400.  
  1401.             if(!DSeg -> Segment)
  1402.             {
  1403.                 if(!FromWorkbench)
  1404.                     Printf("unable to find \33[33mL:DClock-Handler\33[31m\7!\n");
  1405.                 else
  1406.                     PopRequest(NULL,"DClock problem:","Can't find \33[1m\"DClock-Handler\"\33[0m!\nCheck L: and current directory.",NULL,"Continue?",FALSE,NULL);
  1407.  
  1408. Purge:                if(DSeg)
  1409.                 {
  1410.                     if(DSeg -> Port . mp_Node . ln_Name)
  1411.                         FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
  1412.  
  1413.                     if(DSeg -> SoundSemaphore)
  1414.                         FreeMem(DSeg -> SoundSemaphore,sizeof(struct SignalSemaphore));
  1415.  
  1416.                     FreeMem(DSeg,DSeg -> SegSize);
  1417.                 }
  1418.             }
  1419.             else
  1420.             {
  1421.                     /* Install the port and start the handler. */
  1422.  
  1423.                 AddPort(&DSeg -> Port);
  1424.  
  1425.                 CreateProc("DClock-Handler",DSeg -> Priority,DSeg -> Segment,4096);
  1426.  
  1427.                     /* Wait for child task to ring back... */
  1428.  
  1429.                 Wait(SIGBREAKF_CTRL_C);
  1430.  
  1431.                 if(!DSeg -> Child)
  1432.                 {
  1433.                     if(!FromWorkbench)
  1434.                         Printf("\33[33mFAILED!\33[31m (care to retry?)\n");
  1435.                     else
  1436.                         PopRequest(NULL,"DClock problem:","Handler process didn't reply startup-message.",NULL,"Continue?",FALSE,NULL);
  1437.  
  1438.                     RemPort(&DSeg -> Port);
  1439.                     FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
  1440.  
  1441.                     if(DSeg -> Segment)
  1442.                         UnLoadSeg(DSeg -> Segment);
  1443.  
  1444.                     FreeMem(DSeg,DSeg -> SegSize);
  1445.  
  1446.                     if(FromWorkbench)
  1447.                         Delay(TICKS_PER_SECOND * 2);
  1448.  
  1449.                     exit(RETURN_FAIL);
  1450.                 }
  1451.                 else
  1452.                 {
  1453.                     if(!FromWorkbench)
  1454.                         Printf("\33[3mOkay. \33[0m\33[33mDClock v1.%ld\33[31m, by \33[4mMXM\33[0m. \33[1mPUBLIC DOMAIN\33[0m.\n",REVISION);
  1455.                     else
  1456.                         PopRequest(NULL,"DClock Message:","Handler process successfully installed!\n\n\33[33mDClock\33[31m (C) Copyright 1989, 1990 \33[3mby MXM.\33[0m \33[1mPUBLIC DOMAIN\33[0m.",NULL,"Continue?",FALSE,NULL);
  1457.                 }
  1458.             }
  1459.         }
  1460.     }
  1461.  
  1462.         /* Deal with the icon... */
  1463.  
  1464.     if(FromWorkbench)
  1465.     {
  1466.         ProcessIcon();
  1467.         exit(RETURN_OK);
  1468.     }
  1469.  
  1470.         /* Change click volume. */
  1471.  
  1472.     if(argv[ARG_CLICKVOLUME] && DSeg)
  1473.     {
  1474.         if(Atol(argv[ARG_CLICKVOLUME]) >= 0 && Atol(argv[ARG_CLICKVOLUME]) <= 64 )
  1475.         {
  1476.             if(!Quiet)
  1477.                 Printf("\33[1mDClock:\33[0m Click volume set to %ld.\n",DSeg -> ClickVolume = Atol(argv[ARG_CLICKVOLUME]));
  1478.         }
  1479.         else
  1480.             Puts(CLI_Help);
  1481.     }
  1482.  
  1483.         /* Change handler priority? */
  1484.  
  1485.     if(argv[ARG_PRIORITY] && DSeg)
  1486.     {
  1487.         if(DSeg -> Child)
  1488.         {
  1489.             if(!Quiet)
  1490.                 Printf("\33[1mDClock:\33[0m Handler priority set to %ld.\n",DSeg -> Priority = Atol(argv[ARG_PRIORITY]));
  1491.  
  1492.             SetTaskPri(DSeg -> Child,DSeg -> Priority);
  1493.         }
  1494.         else
  1495.             Puts("\33[1mDClock:\33[0m Unable to find handler task.");
  1496.     }
  1497.  
  1498.         /* Turn beeping on/off? */
  1499.  
  1500.     if(argv[ARG_BEEP] && DSeg)
  1501.     {
  1502.         if(!Strcmp(argv[ARG_BEEP],"OFF"))
  1503.         {
  1504.             if(!Quiet)
  1505.                 Puts("\33[1mDClock:\33[0m Beep disabled.");
  1506.  
  1507.             DSeg -> Beep = FALSE;
  1508.         }
  1509.         else
  1510.         {
  1511.             if(!Strcmp(argv[ARG_BEEP],"ON"))
  1512.             {
  1513.                 if(!Quiet)
  1514.                     Puts("\33[1mDClock:\33[0m Beep enabled.");
  1515.  
  1516.                 DSeg -> Beep = TRUE;
  1517.             }
  1518.             else
  1519.                 Puts(CLI_Help);
  1520.         }
  1521.     }
  1522.  
  1523.         /* Turn clicking on/off? */
  1524.  
  1525.     if(argv[ARG_CLICK])
  1526.     {
  1527.         if(!Strcmp(argv[ARG_CLICK],"OFF"))
  1528.         {
  1529.             if(!Quiet)
  1530.                 Puts("\33[1mDClock:\33[0m Click disabled.");
  1531.  
  1532.             DSeg -> Click = FALSE;
  1533.         }
  1534.         else
  1535.         {
  1536.             if(!Strcmp(argv[ARG_CLICK],"ON"))
  1537.             {
  1538.                 if(!Quiet)
  1539.                     Puts("\33[1mDClock:\33[0m Click enabled.");
  1540.  
  1541.                 DSeg -> Click = TRUE;
  1542.             }
  1543.             else
  1544.                 Puts(CLI_Help);
  1545.         }
  1546.     }
  1547.  
  1548.         /* Select new front colour? */
  1549.  
  1550.     if(argv[ARG_TEXTCOLOUR])
  1551.     {
  1552.         DSeg -> TextColour = Atol(argv[ARG_TEXTCOLOUR]);
  1553.  
  1554.         if(!Quiet)
  1555.             Printf("\33[1mDClock:\33[0m Text colour set to %ld.\n",DSeg -> TextColour);
  1556.     }
  1557.  
  1558.         /* Select new background colour? */
  1559.  
  1560.     if(argv[ARG_BACKCOLOUR])
  1561.     {
  1562.         DSeg -> BackColour = Atol(argv[ARG_BACKCOLOUR]);
  1563.  
  1564.         if(!Quiet)
  1565.             Printf("\33[1mDClock:\33[0m Background colour set to %ld.\n",DSeg -> BackColour);
  1566.     }
  1567.  
  1568.         /* Set/check alarm status. */
  1569.  
  1570.     if(argv[ARG_ALARM])
  1571.     {
  1572.         if(!Strcmp(argv[ARG_ALARM],"OFF"))
  1573.         {
  1574.             if(!Quiet)
  1575.                 Puts("\33[1mDClock:\33[0m Alarm disabled.");
  1576.  
  1577.             DSeg -> Alarm = FALSE;
  1578.         }
  1579.         else
  1580.         {
  1581.             if(!Strcmp(argv[ARG_ALARM],"ON"))
  1582.             {
  1583.                 if(!Quiet)
  1584.                     Puts("\33[1mDClock:\33[0m Alarm enabled.");
  1585.  
  1586.                 DSeg -> Alarm = TRUE;
  1587.             }
  1588.             else
  1589.             {
  1590.                 if(!Strcmp(argv[ARG_ALARM],"SHOW"))
  1591.                     Printf("\33[1mDClock:\33[0m Current alarm time is %02ld:%02ld:%02ld.\n",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond);
  1592.                 else
  1593.                     Puts(CLI_Help);
  1594.             }
  1595.         }
  1596.     }
  1597.  
  1598.         /* Adjust alarm time. */
  1599.  
  1600.     if(argv[ARG_ALARMTIME])
  1601.     {
  1602.         char TimeBuff[3];
  1603.         LONG TheTime;
  1604.  
  1605.         TimeBuff[2] = 0;
  1606.  
  1607.         if(strlen(argv[ARG_ALARMTIME]) != 8)
  1608.         {
  1609.             Puts("\33[1mDClock:\33[0m Alarm time format = HH:MM:SS, example: 09:03:07.");
  1610.             exit(RETURN_ERROR);
  1611.         }
  1612.  
  1613.         TimeBuff[0] = argv[ARG_ALARMTIME][0];
  1614.         TimeBuff[1] = argv[ARG_ALARMTIME][1];
  1615.  
  1616.         TheTime = Atol(TimeBuff);
  1617.  
  1618.         if(TheTime < 0 || TheTime > 23)
  1619.         {
  1620.             Puts("\33[1mDClock:\33[0m Illegal time value, Hours must be within 0 ... 23.");
  1621.             exit(RETURN_ERROR);
  1622.         }
  1623.  
  1624.         DSeg -> AlarmHour    = TheTime;
  1625.  
  1626.         TimeBuff[0] = argv[ARG_ALARMTIME][3];
  1627.         TimeBuff[1] = argv[ARG_ALARMTIME][4];
  1628.  
  1629.         TheTime = Atol(TimeBuff);
  1630.  
  1631.         if(TheTime < 0 || TheTime > 59)
  1632.         {
  1633.             Puts("\33[1mDClock:\33[0m Illegal time value, Minutes must be within 0 ... 59.");
  1634.             exit(RETURN_ERROR);
  1635.         }
  1636.  
  1637.         DSeg -> AlarmMinute    = TheTime;
  1638.  
  1639.         TimeBuff[0] = argv[ARG_ALARMTIME][6];
  1640.         TimeBuff[1] = argv[ARG_ALARMTIME][7];
  1641.  
  1642.         TheTime = Atol(TimeBuff);
  1643.  
  1644.         if(TheTime < 0 || TheTime > 59)
  1645.         {
  1646.             Puts("\33[1mDClock:\33[0m Illegal time value, Seconds must be within 0 ... 59.");
  1647.             exit(RETURN_ERROR);
  1648.         }
  1649.  
  1650.         DSeg -> AlarmSecond    = TheTime;
  1651.  
  1652.         if(!Quiet)
  1653.             Printf("\33[1mDClock:\33[0m Alarm time set to %02ld:%02ld:%02ld.\n",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond);
  1654.     }
  1655.  
  1656.     if(argv[ARG_REFRESH])
  1657.     {
  1658.         if(CloseWorkBench())
  1659.             OpenWorkBench();
  1660.  
  1661.         if(!Quiet)
  1662.             Puts("\33[1mDClock:\33[0m Main window refreshed.");
  1663.     }
  1664.  
  1665.         /* Set environment variables? */
  1666.  
  1667.     if(argv[ARG_SETENV])
  1668.     {
  1669.         if(!Strcmp(argv[ARG_SETENV],"OFF"))
  1670.         {
  1671.             if(!Quiet)
  1672.                 Puts("\33[1mDClock:\33[0m Environment variables disabled.");
  1673.  
  1674.             DSeg -> SetEnv = FALSE;
  1675.         }
  1676.         else
  1677.         {
  1678.             if(!Strcmp(argv[ARG_SETENV],"ON"))
  1679.             {
  1680.                 if(!Quiet)
  1681.                     Puts("\33[1mDClock:\33[0m Environment variables enabled.");
  1682.  
  1683.                 DSeg -> SetEnv = TRUE;
  1684.             }
  1685.             else
  1686.                 Puts(CLI_Help);
  1687.         }
  1688.     }
  1689.  
  1690.         /* Set countdown timeout? */
  1691.  
  1692.     if(argv[ARG_COUNTDOWN])
  1693.     {
  1694.         if(Atol(argv[ARG_COUNTDOWN]) > 0)
  1695.         {
  1696.             DSeg -> Countdown = Atol(argv[ARG_COUNTDOWN]);
  1697.  
  1698.             if(!Quiet)
  1699.                 Printf("\33[1mDClock:\33[0m Countdown set to %ld.\n",DSeg -> Countdown);
  1700.         }
  1701.         else
  1702.             Puts(CLI_Help);
  1703.     }
  1704.  
  1705.         /* Enable/disable the hour chime? */
  1706.  
  1707.     if(argv[ARG_HOUR])
  1708.     {
  1709.         if(!Strcmp(argv[ARG_HOUR],"OFF"))
  1710.         {
  1711.             if(!Quiet)
  1712.                 Puts("\33[1mDClock:\33[0m Hour chime disabled.");
  1713.  
  1714.             DSeg -> Hour = FALSE;
  1715.         }
  1716.         else
  1717.         {
  1718.             if(!Strcmp(argv[ARG_HOUR],"ON"))
  1719.             {
  1720.                 if(!Quiet)
  1721.                     Puts("\33[1mDClock:\33[0m Hour chime enabled.");
  1722.  
  1723.                 DSeg -> Hour = TRUE;
  1724.             }
  1725.             else
  1726.                 Puts(CLI_Help);
  1727.         }
  1728.     }
  1729.  
  1730.         /* Display seconds or not? */
  1731.  
  1732.     if(argv[ARG_SECONDS])
  1733.     {
  1734.         if(!Strcmp(argv[ARG_SECONDS],"OFF"))
  1735.         {
  1736.             if(!Quiet)
  1737.                 Puts("\33[1mDClock:\33[0m Seconds disabled.");
  1738.  
  1739.             DSeg -> Seconds = FALSE;
  1740.         }
  1741.         else
  1742.         {
  1743.             if(!Strcmp(argv[ARG_SECONDS],"ON"))
  1744.             {
  1745.                 if(!Quiet)
  1746.                     Puts("\33[1mDClock:\33[0m Seconds enabled.");
  1747.  
  1748.                 DSeg -> Seconds = TRUE;
  1749.             }
  1750.             else
  1751.                 Puts(CLI_Help);
  1752.         }
  1753.     }
  1754.  
  1755.         /* Load a sound file? */
  1756.  
  1757.     if(argv[ARG_SOUND])
  1758.     {
  1759.         if(LoadChimeSound(argv[ARG_SOUND]))
  1760.         {
  1761.             if(!Strcmp(argv[ARG_SOUND],"OFF") && !Quiet)
  1762.                 Puts("\33[1mDClock:\33[0m Chime sound reset.");
  1763.         }
  1764.     }
  1765.  
  1766.         /* Show a special page on startup? */
  1767.  
  1768.     if(argv[ARG_PAGE] && DSeg)
  1769.     {
  1770.         UBYTE Page = Atol(argv[ARG_PAGE]);
  1771.  
  1772.         if(Page >= 0 && Page <= 4 || (Page == 4 && DSeg -> Countdown > 0))
  1773.         {
  1774.             if(!Quiet)
  1775.                 Printf("\33[1mDClock:\33[0m Showing display page %ld.\n",DSeg -> Page = Page);
  1776.         }
  1777.         else
  1778.             Puts("\33[1mDClock:\33[0m Page value out of limits (must be 0-3/4).");
  1779.     }
  1780.  
  1781.         /* Turn the speech on/off? */
  1782.  
  1783.     if(argv[ARG_SPEECH])
  1784.     {
  1785.         if(!Strcmp(argv[ARG_SPEECH],"OFF"))
  1786.         {
  1787.             if(!Quiet)
  1788.                 Puts("\33[1mDClock:\33[0m Speech now off.");
  1789.  
  1790.             DSeg -> Speech = FALSE;
  1791.         }
  1792.         else
  1793.         {
  1794.             if(!Strcmp(argv[ARG_SPEECH],"ON"))
  1795.             {
  1796.                 if(!Quiet)
  1797.                     Puts("\33[1mDClock:\33[0m Speech now on.");
  1798.  
  1799.                 DSeg -> Speech = TRUE;
  1800.             }
  1801.             else
  1802.                 Puts(CLI_Help);
  1803.         }
  1804.     }
  1805.  
  1806.     exit(RETURN_OK);
  1807. }
  1808.